package http

import (
	"github.com/edgexfoundry/edgex-go/internal/app/core/metadata/application"
	requestDTO "github.com/edgexfoundry/edgex-go/internal/app/dtos/requests"
	responseDTO "github.com/edgexfoundry/edgex-go/internal/app/dtos/responses"
	"github.com/edgexfoundry/edgex-go/internal/pkg"
	"github.com/edgexfoundry/edgex-go/internal/pkg/correlation"
	"github.com/edgexfoundry/edgex-go/internal/pkg/utils"
	"github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container"
	"github.com/edgexfoundry/go-mod-core-contracts/v2/common"
	commonDTO "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common"
	"github.com/gorilla/mux"
	"net/http"
)

func (dc *DeviceController) AutoEventAdd(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}

	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()
	correlationId := correlation.FromContext(ctx)

	// URL parameters
	vars := mux.Vars(r)
	deviceId := vars[common.DeviceId]

	var reqDTOs requestDTO.AutoEventAddRequest
	err := dc.reader.Read(r.Body, &reqDTOs)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	reqId := reqDTOs.RequestId
	id, err := application.AutoEventAdd(deviceId, reqDTOs.AutoEvent.ToAutoEventModel(), ctx, dc.dic)

	var response interface{}
	if err != nil {
		lc.Error(err.Error(), common.CorrelationHeader, correlationId)
		lc.Debug(err.DebugMessages(), common.CorrelationHeader, correlationId)
		response = commonDTO.NewBaseResponse(
			reqId,
			err.Message(),
			err.Code())
	} else {
		response = responseDTO.NewDeviceAddResponse(reqId, "", http.StatusCreated, id)
	}

	utils.WriteHttpHeader(w, ctx, http.StatusMultiStatus)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

func (dc *DeviceController) AutoEventGetByDeviceId(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()

	// URL parameters
	vars := mux.Vars(r)
	deviceId := vars[common.DeviceId]

	events, err := application.AutoEventGetByDeviceId(deviceId, ctx, dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := responseDTO.NewDeviceAutoEventResponse("", "", http.StatusOK, events)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

func (dc *DeviceController) AutoEventUpdate(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()

	// URL parameters
	vars := mux.Vars(r)
	deviceId := vars[common.DeviceId]

	var reqDTOs requestDTO.AutoEventUpdateRequest
	err := dc.reader.Read(r.Body, &reqDTOs)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	autoEvent := reqDTOs.AutoEvent.ToAutoEventModel()
	err = application.AutoEventUpdate(deviceId, autoEvent, ctx, dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := commonDTO.NewBaseResponse("", "", http.StatusOK)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

func (dc *DeviceController) AutoEventDelete(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()

	// URL parameters
	vars := mux.Vars(r)
	deviceId := vars[common.DeviceId]

	// URL parameters
	code := utils.ParseQueryStringToString(r, common.Id, "")

	err := application.AutoEventDelete(deviceId, code, ctx, dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := commonDTO.NewBaseResponse("", "", http.StatusOK)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}
